from common import *
import Grunt

class Coordinates(object):
    def __init__(self, (x, y)):
        self.x = x
        self.y = y
    def __add__(self, rhs):
        rhs = ensure(rhs, Coordinates)
        return Coordinates((self.x+rhs.x, self.y+rhs.y))
    def __str__(self):
        return "(%d,%d)" % (self.x, self.y)
    def distanceTo(self, rhs):
        assert isinstance(rhs, Coordinates)
        return int(((self.x-rhs.x)**2+(self.y-rhs.y)**2)**0.5)
        
class Battlespace(object):
    def __init__(self):
        self.grunts = []
        self.teams = {}
        self.teamColors = ['darkgreen', 'darkblue', 'red', 'orange', 'black', 'purple', 'yellow']
        self.readied = False
        self.factory = Grunt.GruntFactory()
        self.effects = []
    def place(self, grunt, coords):
        """Grunt must still be added to a team in the battlespace, but this places it on the board"""
        grunt.coords = ensure(coords, Coordinates)
        #self.grunts.append(grunt)
    def gruntsWithin(self, bottomRight, height, width):
        if not self.readied:
            raise UsageError("Battlespace must be ready() first")
        return self.grunts
    def ready(self):
        teamcount = 0
        xpartition = 30 / len(self.teams)
        for t in self.teams.values():
            """Place only those grunts that are not already placed on the board"""
            xpos = xpartition / 2 + teamcount * xpartition
            gruntcount = 0
            ypartition = 30 / len([g for g in t.grunts if not g.coords]) if len([g for g in t.grunts if not g.coords]) else 0
            for g in t.grunts:
                if not g.coords:
                    ypos = ypartition / 2 + gruntcount * ypartition
                    self.place(g, (xpos, ypos))
                    gruntcount += 1                               
                self.grunts.append(g)
            teamcount += 1
        self.readied = True
        
    def team(self, teamNumber):
        if teamNumber in self.teams:
            return self.teams[teamNumber]
        newTeam = Grunt.Team()
        newTeam.color = self.teamColors[teamNumber]
        self.teams[teamNumber] = newTeam
        return newTeam
    def doAIStuff(self):
        # Set action for all the grunts, possibly re-set other's minds, etc.
        for grunt in self.grunts:
            grunt.mind.act(grunt, self)
    def execute(self):
        for grunt in self.grunts:
            self.effects = []
            grunt.action.perform(grunt, self)
            for effect in self.effects:
                effect.apply(self)
        self.factory.NextTurn()
    
def testSetup(battlespace):
    from Mind import BloodthirstyIdiot
    b = battlespace
    gf = b.factory
    t1 = b.team(1)
    g = gf.NewGrunt()
    b.place(g, (10,10))
    g.name = "A3"
    g.mind = BloodthirstyIdiot()
    t1.add(g)
    g = gf.NewGrunt()
    g.name = "B1"
    g.mind = BloodthirstyIdiot()
    b.team(2).add(g)
    g = gf.NewGrunt()
    g.name = "B2"
    g.mind = BloodthirstyIdiot()
    b.team(2).add(g)
    g = gf.NewGrunt()
    g.name = "B3"
    g.mind = BloodthirstyIdiot()
    b.team(2).add(g)
    g = gf.NewGrunt()
    g.name = "A1"
    g.mind = BloodthirstyIdiot()
    b.team(1).add(g)
    g = gf.NewGrunt()
    g.name = "A2"
    g.mind = BloodthirstyIdiot()
    b.team(1).add(g)
    #b.place(b.team(2).grunts[0], (11,9))
    b.ready()
    b.doAIStuff()
    